/**
 * Simple lexer application, parse input tokens.
 * Add two numbers from the parse script.
 * This implementation done, Berlin Brown (berlin dot brown at gmail.com)
 * 
 * 
 * Variation on code from : "Language Implementation Patterns", Terence Parr
 */
package org.berlin.octane.compiler.app;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import org.berlin.octane.compiler.lang.IntegerNode;
import org.berlin.octane.compiler.lang.PlusNode;
import org.berlin.octane.compiler.lang.SimpleAdderVisitor;
import org.berlin.octane.compiler.lang.VisitorBaseLexer;
import org.berlin.octane.compiler.lang.VisitorSimpleLexer;
import org.berlin.octane.compiler.lang.VisitorToken;

/**
 * Main entry point for Lexer Adder application. Add two numbers together.
 * 
 * Example output:
 * 
 * <pre>
 *  {'(',XL_PAREN}
 *   {'+',XPLUS}
 *   {'100',XDIGIT}
 *   {'200',XDIGIT}
 *   {')',XR_PAREN}
 *   {'_EndOfFile_',XEOF}
 *   Done with parser test.  Continue with AST Test.
 *   -Visit:Plus:{{'+',XPLUS}}-  -Visit:Integer:{{'100',XDIGIT}}- 
 *    -Visit:Integer:{{'200',XDIGIT}}- 
 *   Last Result : 300
 *   LastToken: {'(',XL_PAREN}
 *   LastToken: {'200',XDIGIT}
 *   LastToken: {')',XR_PAREN}
 *   -Visit:Plus:{{'+',XPLUS}}-  -Visit:Integer:{{'100',XDIGIT}}- 
 *    -Visit:Integer:{{'200',XDIGIT}}- 
 *   Last Result : 300
 * </pre>
 */
public class MainFile {

  public static IntegerNode i(final int i) {
    return new IntegerNode(new VisitorToken(VisitorToken.INTEGER, String.valueOf(i)));
  }

  public static PlusNode p(final int a, final int b) {
    return new PlusNode(new VisitorToken(VisitorToken.PLUS, "+"), i(a), i(b));
  }

  /**
   * Main entry point.
   * 
   * @param args
   *          String[]
   */
  public static void main(String[] args) {

    final StringBuffer buf = new StringBuffer(100);
    BufferedReader reader = null;
    try {
      final FileInputStream fis = new FileInputStream(new File("program.mylang"));
      reader = new BufferedReader(new InputStreamReader(fis));
      String data = "";
      do {
        data = reader.readLine();
        if (data != null) {
          buf.append(data);
        }
      } while (data != null);
    } catch (final FileNotFoundException err1) {
      err1.printStackTrace();
      return;
    } catch (final IOException err2) {
      err2.printStackTrace();
      return;
    } finally {
      if (reader != null) {
        try {
          System.out.println("Closing reader...");
          reader.close();
        } catch (final IOException e) {
          e.printStackTrace();
        }
      }
    } // End of try - catch //

    final VisitorSimpleLexer lexer2 = new VisitorSimpleLexer(buf.toString());
    VisitorToken lastToken = lexer2.nextToken();
    PlusNode lastPlusNode = null;
    IntegerNode lastIntNode;
    System.out.println("Parsing input program : [[" + buf.toString() + "]]");
    while (lastToken.getType() != VisitorBaseLexer.EOF_TYPE) {
      System.out.println("LastToken: " + lastToken);
      lastToken = lexer2.nextToken();
      if (VisitorToken.PLUS == lastToken.getType()) {
        lastToken = lexer2.nextToken();
        IntegerNode arg1 = null;
        IntegerNode arg2 = null;
        if (VisitorToken.INTEGER == lastToken.getType()) {
          lastIntNode = i(Integer.parseInt(lastToken.getText()));
          arg1 = lastIntNode;
        }
        lastToken = lexer2.nextToken();
        if (VisitorToken.INTEGER == lastToken.getType()) {
          lastIntNode = i(Integer.parseInt(lastToken.getText()));
          arg2 = lastIntNode;
        }
        lastPlusNode = new PlusNode(new VisitorToken(VisitorToken.PLUS, "+"), arg1, arg2);
      } // End of If //

    } // End of the While //
    final SimpleAdderVisitor visitor = new SimpleAdderVisitor();
    visitor.visit(lastPlusNode);
    System.out.println("Last Result : " + visitor.getLastResult());
  }

} // End of the class //
